package com.notetool.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.TreeSet;

public class Note implements Comparable<Note>
{

    ////////////////////
    // Members
    private String id;
    private TreeSet<String> tags;
    private ArrayList<NoteEventListener> listeners;
    
    ////////////////////
    // Constructors
    public Note (String newId)
    {
        id = newId;
        tags = new TreeSet<String> ();
        listeners = new ArrayList<NoteEventListener> ();
    }
    
    ////////////////////
    // Accessors
    public String getId ()
    {
        return id;
    }
    
    public void setId (String id)
    {
        this.id = id;
    }
    
    public TreeSet<String> getTags ()
    {
        return new TreeSet<String> (tags);
    }
    
    public void setTags (TreeSet<String> newTags)
    {
        if (newTags == null)
            return;
        
        // Clone the new tags set, as we'll need to work on it
        TreeSet<String> tagsCopy = new TreeSet<String> (newTags);
        
        // Loop through the original set
        Iterator<String> oldSet = tags.iterator ();
        
        while (oldSet.hasNext ())
        {
            String oldTag = oldSet.next ();
            
            // Remove from new set if exists in there, as we already have that tag
            boolean exists = tagsCopy.remove (oldTag);
            
            // If we couldn't find it in the new set, then remove it from the current set
            if (!exists)
            {
                oldSet.remove ();
                triggerTagRemoved (oldTag);
            }
        }
        
        // Loop through the new set
        for (String newTag : tagsCopy)
        {
            // Add each tag still present
            addTag (newTag);
        }
    }
    
    ////////////////////
    // Comparable<Note> implementation 
    public int compareTo (Note note)
    {
        return id.compareTo (note.getId ());
    }
    
    ////////////////////
    // Public methods
    public void addTag (String tag)
    {
        boolean added = tags.add (tag);
        if (added)
            triggerTagAdded (tag);
    }
    
    public void addTags (String[] newTags)
    {
        if (newTags == null)
            return;
        
        for (String tag : newTags)
            addTag (tag);
    }
    
    public void removeTag (String tag)
    {
        boolean added = tags.remove (tag);
        if (added)
            triggerTagRemoved (tag);
    }
    
    public void addEventListener (NoteEventListener listener)
    {
        if (!listeners.contains (listener))
            listeners.add (listener);
    }
    
    public void removeEventListener (NoteEventListener listener)
    {
        listeners.remove (listener);
    }
    
    ////////////////////
    // Private methods
    public void triggerTagAdded (String tag)
    {
        for (NoteEventListener listener : listeners)
            listener.tagAdded (this, tag);
    }
    
    public void triggerTagRemoved (String tag)
    {
        for (NoteEventListener listener : listeners)
            listener.tagRemoved (this, tag);
    }
    
}
